﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Opc.Da;
using System.Windows.Forms;
using TI_4_Limonade_Fabriek.Logging;
using TI_4_Limonade_Fabriek.Database;
using TI_4_Limonade_Fabriek.Model;

namespace TI_4_Limonade_Fabriek.OPC
{
    class OPCController
    {
        private const string path = "LIMONADEFABRIEK>PLC1>";
        private Opc.Da.Server server;
        private int amountTags;
        ErrorLogging el;
        public OpcCom.Factory factory = new OpcCom.Factory();
        private Opc.Da.Subscription group;
        public List<Batch> batchList;

        public OPCController(string groupName)
        {
            //Nieuwe server aanmaken
            server = new Server(factory, null);

            //Nieuwe factory aanmaken
            factory = new OpcCom.Factory();

            //Errorlogging en batchlogging initialiseren
            el = new ErrorLogging();

            batchList = new List<Batch>();
            try
            {
                //Verbinden met de server
                server.Connect(new Opc.URL("opcda://localhost/Tunneller:172.16.4.153:Matrikon.OPC.SiemensPLC.1"), new Opc.ConnectData(new System.Net.NetworkCredential()
                {
                    UserName = "administrator",
                    Password = "WaarIsWally"
                }));

                //Group op de OPC aanmaken
                Opc.Da.SubscriptionState groupState = new Opc.Da.SubscriptionState();
                groupState.Name = groupName;
                groupState.Active = true;
                groupState.UpdateRate = 1000;
                group = (Opc.Da.Subscription)server.CreateSubscription(groupState);

                CreateTags();
            }
            catch (Exception)
            {
                MessageBox.Show("Geen connectie met de OPC server.");
                el.LogErrorMsg("Kan niet verbinden met de OPC server");
            }
        }

        private void CreateTags()
        {
            try
            {
                TagWriter tagWriter = new TagWriter();
                List<string> tags = new List<string>();
                tags = tagWriter.ReadTags();
                //Lees alle tags uit de tekstfile Tags.txt
                Opc.Da.Item[] items = new Opc.Da.Item[tags.Count()];
                for (int i = 0; i < items.Length; i++)
                {
                    items[i] = new Opc.Da.Item() { ItemName = path + tags[i] };
                }
                //Voeg alle tags uit de tekst file toe aan de OPC group
                group.AddItems(items);
                amountTags = tags.Count();
            }
            catch (Exception e)
            {
                MessageBox.Show("Tags kunnen niet gemaakt worden.");
                el.LogErrorMsg(e.Message);
            }
        }

        public void WriteTags(string tag, int waarde)
        {
            try
            {
                //Lees alle huidige tags uit de OPC
                Opc.Da.ItemValue[] writeValues = new Opc.Da.ItemValue[amountTags];
                for (int i = 0; i < amountTags; i++)
                {
                    writeValues[i] = new Opc.Da.ItemValue();
                    writeValues[i].ServerHandle = group.Items[i].ServerHandle;
                    writeValues[i].ItemName = group.Items[i].ItemName;
                }

                for (int i = 0; i < amountTags; i++)
                {
                    //Vind de tag die veranderd moet worden
                    if (writeValues[i].ItemName == path + tag)
                    {
                        writeValues[i].Value = waarde;
                        break;
                    }
                }
                //Write alle nieuwe waardes naar de OPC
                group.Write(writeValues);
            }
            catch (Exception e)
            {
                el.LogErrorMsg(e.Message);
                MessageBox.Show("Tags kunnen niet geschreven worden");
            }

        }

        public string ReadTags(string tag)
        {
            if (server.IsConnected)
            {
                try
                {
                Opc.Da.ItemValue[] readValues = new Opc.Da.ItemValue[amountTags];

                for (int i = 0; i < amountTags; i++)
                {
                        //Zoek de tag die gelijk is aan de meegegeven tag
                        if (group.Items[i].ItemName == path + tag)
                        {
                            readValues = group.Read(group.Items);
                            //Return de waarde van de tag
                            return readValues[i].Value.ToString();
                            
                        }
                    }
                    return null;
                }
                catch (Exception e)
                {
                    el.LogErrorMsg(e.ToString());
                    MessageBox.Show("Tags kunnen niet gelezen worden" + " " + tag);
                    return null;
                }
            }
            else
            {
                MessageBox.Show("Connectie verloren");
                el.LogErrorMsg("Connectie verloren" + DateTime.Now);
                return null;
            }
        }

        public void Stop()
        {
            //Disconnect de OPC server
            server.Disconnect();
        }
    }
}
